package com.mbbmap.app.manager;

import java.io.FileWriter;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * ApplicationLogManager is implemented as a variant of a Singleton
 * which controls logging of application messages to a logfile.
 * The ApplicationLogManager differs from the SystemLogManager in that it
 * is mainly used to log the status of events and/or transactions that occur
 * during a normal run of system. The SystemLogManager, on the other hand,
 * mainly logs error conditions or abnormal exceptions that occur.
 * The location of the application log is determined by the "AppLogFile" entry in
 * the <i>system.properties</i> file. The default file name is "app.log" if such an entry does not exist.
 * <p>
 * Usage of this class assumes that the ConfigManager class has been
 * loaded with the properties from the config file.
 * <p>
 */
public class ApplicationLogManager {
	private static PrintWriter log = null;
	private static String logFile = null;
	private static ApplicationLogManager instance = null;

	private static final String defaultFilePath = "/app.log";

	private ApplicationLogManager() {
		super();
	}

    /**
     * Returns the single instance, creating one if it's the
     * first time this method is called.
     *
     * @return ApplicationLogManager. The single instance.
     */
	public static ApplicationLogManager getInstance() {
		//thread-safe implementation
		if (instance == null) {
			synchronized (ApplicationLogManager.class) {
				if (instance == null) {
					instance = new ApplicationLogManager();
					if ((logFile = ConfigManager.getInstance().get("AppLogFile")) == null) {
						logFile = defaultFilePath;
					}
				}
			}
		}
		return instance;
	}

	/**
     * Logs info or status messages to the log
     *
     * @param message The info message to be logged
     */
	public void logMsg(String message) {
		log(message);
	}

	private void getResources() throws Exception {
		//set with file write append (second boolean parameter)
		//set without autoflush in PrintWriter
		log = new PrintWriter(new FileWriter(logFile, true));
	}

	private void releaseResources() {
		if (log != null)
			log.close();
	}

	//NOTE: As long as ALL modifications to the content of the log is done
	//      through this synchronized method, there is no need to synchronize
	//      the rest of the methods.

	private synchronized void log(String message) {

		Date todaysDate = Calendar.getInstance().getTime();
		DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG,
			DateFormat.SHORT);
		try {
			getResources();
			//logging of error messages
			log.println("[" + df.format(todaysDate) + "] : " + message);
			log.flush();
		} catch (Exception e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
		releaseResources();
	}
}
